﻿using FarmerJoe.Helpers.Units;
using Styx;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using System.Linq;

namespace FarmerJoe.Helpers
{
    public static class CLC
    {
        // This is what I call my "Common Language Configuration" system.

        public static string RawSetting { get; set; }
        private static LocalPlayer Me { get { return StyxWoW.Me; } }
        private static WoWUnit ValidateAgainstUnit { get; set; }

        /// <summary>
        /// If 'ValidateAgainstUnit' is not null use that, otherwise, use the current target
        /// </summary>
        public static WoWUnit CT{get{if (ValidateAgainstUnit != null) return ValidateAgainstUnit;return Me.GotTarget ? Me.CurrentTarget : null;}}

        private static bool OnAdds { get { return RawSetting.Contains("only on adds"); } }
        private static bool NoAdds { get { return RawSetting.Contains("only when no adds"); } }
        private static bool OnAdds3OrMore { get { return RawSetting.Contains("only on 3+ adds"); } }
        private static bool OnAdds4OrMore { get { return RawSetting.Contains("only on 4+ adds"); } }
        private static bool OnAdds5OrMore { get { return RawSetting.Contains("only on 5+ adds"); } }
        private static bool OnAdds6OrMore { get { return RawSetting.Contains("only on 6+ adds"); } }
        private static bool OnAdds7OrMore { get { return RawSetting.Contains("only on 7+ adds"); } }
        private static bool OnAdds8OrMore { get { return RawSetting.Contains("only on 8+ adds"); } }


        private static bool Always { get { return RawSetting.Contains("always"); } }
        private static bool Never { get { return RawSetting.Contains("never"); } }
        private static bool OnRunners { get { return RawSetting.Contains("on runners") || RawSetting.Contains("and runners"); } }
        private static bool IfCasting { get { return RawSetting.Contains("on casters") || RawSetting.Contains("casters and"); } }
        //private static bool IsCasting { get { return RawSetting.Contains("mob is casting"); } }
        private static bool IfTargetCasting { get { return RawSetting.Contains("target is casting"); } }
        private static bool IfCastingOrRunning { get { return RawSetting.Contains("casters and runners"); } }
        private static bool OutOfCombat { get { return RawSetting.Contains("out of combat") || RawSetting.Contains("during pull"); } }
        private static bool InCombat { get { return RawSetting.Contains("in combat") || RawSetting.Contains("during combat"); } }
        private static bool Immediately { get { return RawSetting.Contains("immediately"); } }
        private static bool InBGs { get { return RawSetting.Contains("only in battleground") || RawSetting.Contains("when in battleground"); } }
        private static bool NotInBGs { get { return RawSetting.Contains("not in battleground"); } }
        private static bool InInstances { get { return RawSetting.Contains("only when in instance") || RawSetting.Contains("inside an instance") || RawSetting.Contains("only in instance"); } }
        private static bool NotInInstances { get { return RawSetting.Contains("not in instance") || RawSetting.Contains("not inside an instance"); } }
        private static bool OnHumanoids { get { return RawSetting.Contains("on humanoids"); } }
        private static bool OnUndead { get { return RawSetting.Contains("undead"); } }
        private static bool OnDemons { get { return RawSetting.Contains("demons"); } }
        private static bool OnBeasts { get { return RawSetting.Contains("beasts"); } }
        private static bool OnElementals { get { return RawSetting.Contains("elemental"); } }
        private static bool OnFleeing { get { return RawSetting.Contains("on fleeing") || RawSetting.Contains("is fleeing") || RawSetting.Contains("or fleeing"); } }
        private static bool NotLowLevel { get { return RawSetting.Contains("not low level"); } }
        private static bool IsHigherLevel { get { return RawSetting.Contains("is higher level"); } }
        private static bool IsInMeleeRange { get { return RawSetting.Contains("is in melee range"); } }
        private static bool InMeleeRange { get { return RawSetting.Contains("in melee range"); } }
        //private static bool IsBoss { get { return RawSetting.Contains("is Boss"); } }

        private static bool IsPlayer { get { return RawSetting.Contains("is player"); } }
        private static bool IsNotPlayer { get { return RawSetting.Contains("is not player"); } }
        private static bool IsInParty { get { return RawSetting.Contains("when in party"); } }
        private static bool IsNotInParty { get { return RawSetting.Contains("not in party"); } }
        private static bool IsInRaid { get { return RawSetting.Contains("when in raid"); } }
        private static bool IsNotInRaid { get { return RawSetting.Contains("when not in raid"); } }

        private static bool GoHard { get { return RawSetting.Contains("go hard"); } }

        // Combo points - Rogues and Druids (Cat)
        private static bool ComboPoints12 { get { return RawSetting.Contains("1-2 combo"); } }
        private static bool ComboPoints23 { get { return RawSetting.Contains("2-3 combo"); } }
        private static bool ComboPoints34 { get { return RawSetting.Contains("3-4 combo"); } }
        private static bool ComboPoints45 { get { return RawSetting.Contains("4-5 combo"); } }
        private static bool ComboPoints1OrMore { get { return RawSetting.Contains("1+ Combo") || RawSetting.Contains("1+ combo"); } }
        private static bool ComboPoints2OrMore { get { return RawSetting.Contains("2+ Combo") || RawSetting.Contains("2+ combo"); } }
        private static bool ComboPoints3OrMore { get { return RawSetting.Contains("3+ Combo") || RawSetting.Contains("3+ combo"); } }
        private static bool ComboPoints4OrMore { get { return RawSetting.Contains("4+ Combo") || RawSetting.Contains("4+ combo"); } }
        private static bool ComboPoints5OrMore { get { return RawSetting.Contains("5+ Combo") || RawSetting.Contains("5+ combo"); } }

        // Holy Power - Paladin only
        private static bool HolyPower1OrMore { get { return RawSetting.Contains("1+ Holy Power"); } }
        private static bool HolyPower2OrMore { get { return RawSetting.Contains("2+ Holy Power"); } }
        private static bool HolyPower3OrMore { get { return RawSetting.Contains("3+ Holy Power"); } }

        // Prist Only - Dark Evangelism
        private static bool DarkEvangelism1OrMore { get { return RawSetting.Contains("1+ Dark Evangelism"); } }
        private static bool DarkEvangelism2OrMore { get { return RawSetting.Contains("2+ Dark Evangelism"); } }
        private static bool DarkEvangelism3OrMore { get { return RawSetting.Contains("3+ Dark Evangelism"); } }
        private static bool DarkEvangelism4OrMore { get { return RawSetting.Contains("4+ Dark Evangelism"); } }
        private static bool DarkEvangelism5OrMore { get { return RawSetting.Contains("5+ Dark Evangelism"); } }

        // Priest only - Shadow Orbs
        private static bool MindSpike1OrMore { get { return RawSetting.Contains("1+ Mind Spike"); } }
        private static bool MindSpike2OrMore { get { return RawSetting.Contains("2+ Mind Spike"); } }
        private static bool MindSpike3OrMore { get { return RawSetting.Contains("3+ Mind Spike"); } }
        private static bool ShadowOrb1OrMore { get { return RawSetting.Contains("1+ Shadow Orb"); } }
        private static bool ShadowOrb2OrMore { get { return RawSetting.Contains("2+ Shadow Orb"); } }
        private static bool ShadowOrb3OrMore { get { return RawSetting.Contains("3+ Shadow Orb"); } }
        private static bool InShadowform { get { return RawSetting.Contains("only in Shadowform") || RawSetting.Contains("only when in Shadowform"); } }
        private static bool NotInShadowform { get { return RawSetting.Contains("not in Shadowform"); } }

        // Hunter Focus Fire Frenzy Stacks
        private static bool FocusFire1OrMore { get { return RawSetting.Contains("1+ Frenzy"); } }
        private static bool FocusFire2OrMore { get { return RawSetting.Contains("2+ Frenzy"); } }
        private static bool FocusFire3OrMore { get { return RawSetting.Contains("3+ Frenzy"); } }
        private static bool FocusFire4OrMore { get { return RawSetting.Contains("4+ Frenzy"); } }
        private static bool FocusFire5OrMore { get { return RawSetting.Contains("5+ Frenzy"); } }

        // Hunter Focus 
        private static bool Focus2OrMore { get { return RawSetting.Contains("focus 20+"); } }
        private static bool Focus25rMore { get { return RawSetting.Contains("focus 25+"); } }
        private static bool Focus3OrMore { get { return RawSetting.Contains("focus 30+"); } }
        private static bool Focus35rMore { get { return RawSetting.Contains("focus 35+"); } }
        private static bool Focus4OrMore { get { return RawSetting.Contains("focus 40+"); } }
        private static bool Focus45rMore { get { return RawSetting.Contains("focus 45+"); } }
        private static bool Focus5OrMore { get { return RawSetting.Contains("focus 50+"); } }
        private static bool Focus55rMore { get { return RawSetting.Contains("focus 55+"); } }
        private static bool Focus6OrMore { get { return RawSetting.Contains("focus 60+"); } }
        private static bool Focus65rMore { get { return RawSetting.Contains("focus 65+"); } }
        private static bool Focus7OrMore { get { return RawSetting.Contains("focus 70+"); } }
        private static bool Focus75rMore { get { return RawSetting.Contains("focus 75+"); } }
        private static bool Focus8OrMore { get { return RawSetting.Contains("focus 80+"); } }
        private static bool Focus85rMore { get { return RawSetting.Contains("focus 85+"); } }
        private static bool Focus9OrMore { get { return RawSetting.Contains("focus 90+"); } }
        private static bool Focus95rMore { get { return RawSetting.Contains("focus 95+"); } }

        // Health
        private static bool HealthLessThan90 { get { return RawSetting.Contains("health below 90"); } }
        private static bool HealthLessThan80 { get { return RawSetting.Contains("health below 80"); } }
        private static bool HealthLessThan70 { get { return RawSetting.Contains("health below 70"); } }
        private static bool HealthLessThan60 { get { return RawSetting.Contains("health below 60"); } }
        private static bool HealthLessThan50 { get { return RawSetting.Contains("health below 50"); } }
        private static bool HealthLessThan40 { get { return RawSetting.Contains("health below 40"); } }
        private static bool HealthLessThan30 { get { return RawSetting.Contains("health below 30"); } }
        private static bool HealthLessThan20 { get { return RawSetting.Contains("health below 20"); } }

        // Target Health
        private static bool TargetHealthLessThan75 { get { return RawSetting.Contains("target health % < 75"); } }
        private static bool TargetHealthLessThan50 { get { return RawSetting.Contains("target health % < 50"); } }
        private static bool TargetHealthLessThan25 { get { return RawSetting.Contains("target health % < 25"); } }

        // My Health
        private static bool MyHealthLessThan75 { get { return RawSetting.Contains("my health % < 75"); } }
        private static bool MyHealthLessThan60 { get { return RawSetting.Contains("my health % < 60"); } }
        private static bool MyHealthLessThan50 { get { return RawSetting.Contains("my health % < 50"); } }
        private static bool MyHealthLessThan35 { get { return RawSetting.Contains("my health % < 35"); } }
        private static bool MyHealthLessThan25 { get { return RawSetting.Contains("my health % < 25"); } }

        private static bool TargetLessThan75 { get { return RawSetting.Contains("target < 75% health"); } }
        private static bool TargetLessThan50 { get { return RawSetting.Contains("target < 50% health"); } }
        private static bool TargetLessThan25 { get { return RawSetting.Contains("target < 25% health"); } }

        private static bool TargetHealthMoreThan75 { get { return RawSetting.Contains("target health % > 75"); } }
        private static bool TargetHealthMoreThan50 { get { return RawSetting.Contains("target health % > 50"); } }
        private static bool TargetHealthMoreThan25 { get { return RawSetting.Contains("target health % > 25"); } }

        private static bool TargetMoreThan75 { get { return RawSetting.Contains("target > 75% health"); } }
        private static bool TargetMoreThan50 { get { return RawSetting.Contains("target > 50% health"); } }
        private static bool TargetMoreThan25 { get { return RawSetting.Contains("target > 25% health"); } }

        // Stacks
        private static bool Stacks1OrMore { get { return RawSetting.Contains("1+ stacks"); } }
        private static bool Stacks2OrMore { get { return RawSetting.Contains("2+ stacks"); } }
        private static bool Stacks3OrMore { get { return RawSetting.Contains("3+ stacks"); } }
        private static bool Stacks4OrMore { get { return RawSetting.Contains("4+ stacks"); } }
        private static bool Stacks5OrMore { get { return RawSetting.Contains("5+ stacks"); } }

        // Warlock
        private static bool SoulShard0 { get { return RawSetting.Contains("0 soul shard"); } }
        private static bool SoulShard1 { get { return RawSetting.Contains("1 soul shard"); } }
        private static bool SoulShard2 { get { return RawSetting.Contains("2 soul shard"); } }
        private static bool SoulShard3 { get { return RawSetting.Contains("3 soul shard"); } }
        private static bool MoltenCore { get { return RawSetting.Contains("Molten Core"); } }
        private static bool Immolate { get { return RawSetting.Contains("Immolate"); } }
        private static bool Decimation { get { return RawSetting.Contains("Decimation"); } }

        /// <summary>
        /// Returns TRUE is the spell/setting is OK can it passed the various checks requested
        /// </summary>
        public static bool IsOkToRun
        {
            get
            {
                try
                {
                    if (string.IsNullOrEmpty(RawSetting)) return false;                                                 // No string passed so nothing to check
                    if (Always || Immediately) return true;                                                             // Always means always
                    if (Never) return false;                                                                            // No means no! You men are all the same
                    if (OutOfCombat && !Me.Combat) return true;                                                         // Only if we're not in combat
                    if (InCombat && Me.Combat) return true;                                                         // Only if we're not in combat
                    if (RawSetting.Contains("+ adds") && AddsAndOthers.AddCount <= 1) return false;
                    if (OnAdds && AddsAndOthers.AddCount > 1 && Me.Combat) return true;                                                               // Only if we have adds
                    if (NoAdds && AddsAndOthers.AddCount <= 1 && Me.Combat) return true;                                                               // Only if we DON'T have adds
                    if (CT != null && IfCastingOrRunning && ((CT.IsCasting && CT.CastingSpell.CastTime>1) || CT.Fleeing)) return true;    // Only if the target is casting or running
                    if (OnRunners && CT != null && CT.Fleeing) return true;                                              // Only if target (NPC) is running away
                    if ((IfCasting || IfTargetCasting) && CT != null && (CT.IsCasting && CT.CastingSpell.CastTime > 1)) return true;                                            // Only if target is casting
                    if (InInstances && Me.IsInInstance) return true;                                                    // Only if you are inside an instance
                    if (InBGs && Battlegrounds.IsInsideBattleground) return true;                                                     // Only if you are inside a battleground
                    if (NotInBGs && !Battlegrounds.IsInsideBattleground) return true;                                                     // Only if you are NOT inside a battleground
                    if (OnHumanoids && CT != null && CT.CreatureType == WoWCreatureType.Humanoid) return true;  // Humanoids only. Mostly for runners
                    if (OnUndead && CT != null && CT.CreatureType == WoWCreatureType.Undead) return true;
                    if (OnDemons && CT != null && CT.CreatureType == WoWCreatureType.Demon) return true;
                    if (OnBeasts && CT != null && CT.CreatureType == WoWCreatureType.Beast) return true;
                    if (OnElementals && CT != null && CT.CreatureType == WoWCreatureType.Elemental) return true;
                    if (OnFleeing && CT != null && CT.Fleeing) return true;  // Is target fleeing
                    if (NotInInstances && !Me.IsInInstance) return true;
                    if (NotLowLevel && CT != null && !CT.IsLowLevel()) return true;
                    //if (IsHighLevel && CT != null && CT.IsHighLevel()) return true;
                    if (IsHigherLevel && CT != null && ((CT.Level > Me.Level || CT.Elite) || CT.IsHighLevel())) return true;

                    if ((IsInMeleeRange || InMeleeRange) && CT != null && CT.Distance <= CT.InteractRange * 1.2) return true;
                    if (CT != null && IsPlayer && CT.IsPlayer) return true;
                    if (CT != null && IsNotPlayer && !CT.IsPlayer) return true;
                    if (IsInParty && Me.GroupInfo.IsInParty) return true;
                    if (IsNotInParty && !Me.GroupInfo.IsInParty) return true;
                    if (IsInRaid && Me.GroupInfo.IsInRaid) return true;
                    if (IsNotInRaid && !Me.GroupInfo.IsInRaid) return true;
                    if (GoHard && Battlegrounds.IsInsideBattleground) return true;

                    if (MyHealthLessThan75 && Me.HealthPercent <= 75) return true;
                    if (MyHealthLessThan60 && Me.HealthPercent <= 60) return true;
                    if (MyHealthLessThan50 && Me.HealthPercent <= 50) return true;
                    if (MyHealthLessThan35 && Me.HealthPercent <= 35) return true;
                    if (MyHealthLessThan25 && Me.HealthPercent <= 25) return true;

                    //if (CT != null && HealingSpellCast && CT.IsCasting && Utils.Healing.Any(spell => CT.CastingSpell.Id == spell)) return true;
                    //if (CT != null && InstanceImportantSpellCast && CT.IsCasting && Utils.ImportantInterruptSpells.Any(spell => CT.CastingSpell.Id == spell)) return true;

                    // X+ AddsAndOthers
                    if (RawSetting.Contains("+ adds"))
                    {
                        if (OnAdds3OrMore && AddsAndOthers.AddCount >= 3) return true;
                        if (OnAdds4OrMore && AddsAndOthers.AddCount >= 4) return true;
                        if (OnAdds5OrMore && AddsAndOthers.AddCount >= 5) return true;
                        if (OnAdds6OrMore && AddsAndOthers.AddCount >= 6) return true;
                        if (OnAdds7OrMore && AddsAndOthers.AddCount >= 7) return true;
                        if (OnAdds8OrMore && AddsAndOthers.AddCount >= 8) return true;
                    }

                    // Target health PERCENT
                    if (RawSetting.Contains("target health %") || RawSetting.Contains("target <") || RawSetting.Contains("target >"))
                    {
                        if (CT != null) return false;
                        if (CT != null && CT.IsDead) return false;

                        // Less than...
                        if (CT != null && ((TargetHealthLessThan75 || TargetLessThan75) && CT.HealthPercent <= 75)) return true;
                        if (CT != null && ((TargetHealthLessThan50 || TargetLessThan50) && CT.HealthPercent <= 50)) return true;
                        if (CT != null && ((TargetHealthLessThan25 || TargetLessThan25) && CT.HealthPercent <= 25)) return true;
                        if (CT != null && (CT.HealthPercent <= 25 && RawSetting.Contains("target < 25% health"))) return false;

                        // More than...
                        if (CT != null && ((TargetHealthMoreThan75 || TargetMoreThan75) && CT.HealthPercent >= 75)) return true;
                        if (CT != null && ((TargetHealthMoreThan50 || TargetMoreThan50) && CT.HealthPercent >= 50)) return true;
                        if (CT != null && ((TargetHealthMoreThan25 || TargetMoreThan25) && CT.HealthPercent >= 25)) return true;

                    }

                    // Health < X
                    if (RawSetting.Contains("health below"))
                    {
                        if (HealthLessThan90 && Me.HealthPercent < 90) return true;
                        if (HealthLessThan80 && Me.HealthPercent < 80) return true;
                        if (HealthLessThan70 && Me.HealthPercent < 70) return true;
                        if (HealthLessThan60 && Me.HealthPercent < 60) return true;
                        if (HealthLessThan50 && Me.HealthPercent < 50) return true;
                        if (HealthLessThan40 && Me.HealthPercent < 40) return true;
                        if (HealthLessThan30 && Me.HealthPercent < 30) return true;
                        if (HealthLessThan20 && Me.HealthPercent < 20) return true;
                    }

                    //if (IsBoss && CT != null && CT.IsBoss()) return true;

                    // If you are not a Rogue or a Druid (Cat) then don't do these checks
                    if (Me.Class == WoWClass.Rogue || Me.Class == WoWClass.Druid && Me.Shapeshift == ShapeshiftForm.Cat)
                    {
                        if (Me.ComboPoints <= 0) return false;
                        if (ComboPoints45 && Me.ComboPoints >= 4) return true;
                        if (ComboPoints34 && (Me.ComboPoints >= 3 && Me.ComboPoints <= 4)) return true;
                        if (ComboPoints23 && (Me.ComboPoints >= 2 && Me.ComboPoints <= 3)) return true;
                        if (ComboPoints12 && (Me.ComboPoints >= 1 && Me.ComboPoints <= 2)) return true;

                        if (ComboPoints1OrMore && Me.ComboPoints >= 1) return true;
                        if (ComboPoints2OrMore && Me.ComboPoints >= 2) return true;
                        if (ComboPoints3OrMore && Me.ComboPoints >= 3) return true;
                        if (ComboPoints4OrMore && Me.ComboPoints >= 4) return true;
                        if (ComboPoints5OrMore && Me.ComboPoints >= 5) return true;
                    }

                    if (Me.Class == WoWClass.Paladin)
                    {
                        //if (Me.CurrentHolyPower <= 0) return false;
                        if (HolyPower1OrMore && Me.CurrentHolyPower >= 1) return true;
                        if (HolyPower2OrMore && Me.CurrentHolyPower >= 2) return true;
                        if (HolyPower3OrMore && Me.CurrentHolyPower >= 3) return true;

                        // Other Misc
                        //if (RawSetting.Contains("Sacred Duty") && IsBuffPresent("Sacred Duty")) return true;
                    }

                    if (Me.Class == WoWClass.Priest)
                    {
                        /*
                        // Archangel / Evangelism
                        if (Stacks1OrMore && Me.StackCountLUA("Evangelism") >= 1) return true;
                        if (Stacks2OrMore && Me.StackCountLUA("Evangelism") >= 2) return true;
                        if (Stacks3OrMore && Me.StackCountLUA("Evangelism") >= 3) return true;
                        if (Stacks4OrMore && Me.StackCountLUA("Evangelism") >= 4) return true;
                        if (Stacks5OrMore && Me.StackCountLUA("Evangelism") >= 5) return true;

                        if (Stacks1OrMore && Me.StackCountLUA("Dark Evangelism") >= 1) return true;
                        if (Stacks2OrMore && Me.StackCountLUA("Dark Evangelism") >= 2) return true;
                        if (Stacks3OrMore && Me.StackCountLUA("Dark Evangelism") >= 3) return true;
                        if (Stacks4OrMore && Me.StackCountLUA("Dark Evangelism") >= 4) return true;
                        if (Stacks5OrMore && Me.StackCountLUA("Dark Evangelism") >= 5) return true;

                        if (DarkEvangelism1OrMore && Me.StackCountLUA("Dark Evangelism") >= 1) return true;
                        if (DarkEvangelism2OrMore && Me.StackCountLUA("Dark Evangelism") >= 2) return true;
                        if (DarkEvangelism3OrMore && Me.StackCountLUA("Dark Evangelism") >= 3) return true;
                        if (DarkEvangelism4OrMore && Me.StackCountLUA("Dark Evangelism") >= 4) return true;
                        if (DarkEvangelism5OrMore && Me.StackCountLUA("Dark Evangelism") >= 5) return true;

                        if (InShadowform && Me.IsAuraIDOnUnit(15473, Unit.AuraCheck.AllAuras)) return true;
                        if (NotInShadowform && !Me.IsAuraIDOnUnit(15473, Unit.AuraCheck.AllAuras)) return true;

                        //if (!Self.IsBuffOnMe(87178, Self.AuraCheck.AllAuras)) return false;
                        int mindSpikeCount = Unit.CT.AuraStackCount("Mind Spike");
                        //int mindSpikeCount = Target.StackCount(87178);
                        if (MindSpike1OrMore && mindSpikeCount >= 1) return true;
                        if (MindSpike2OrMore && mindSpikeCount >= 2) return true;
                        if (MindSpike3OrMore && mindSpikeCount >= 3) return true;

                        // If no Shadow Orbs then bail out now. 
                        if (!Me.IsAuraIDOnUnit(77487, Unit.AuraCheck.AllAuras)) return false;

                        int orbCount = Me.AuraStackCount(77487);
                        if (ShadowOrb1OrMore && orbCount >= 1) return true;
                        if (ShadowOrb2OrMore && orbCount >= 2) return true;
                        if (ShadowOrb3OrMore && orbCount >= 3) return true;
                         */

                    }

                    if (Me.Class == WoWClass.Warlock)
                    {
                        if (SoulShard0 && Me.CurrentSoulShards <= 0) return true;
                        if (SoulShard1 && Me.CurrentSoulShards <= 1) return true;
                        if (SoulShard2 && Me.CurrentSoulShards <= 3) return true;
                        if (SoulShard3 && Me.CurrentSoulShards <= 3) return true;
                        if (MoltenCore && Me.HasAura(71165)) return true;
                        if (Decimation && (Me.HasAura(63165) || Me.HasAura(63167))) return true;
                        //if (Immolate && CT != null && IsBuffPresentOnTarget("Immolate")) return true;
                        //if (Immolate && CT != null && CT.HasAura("Immolate")) return true;


                    }

                    if (Me.Class == WoWClass.Hunter)
                    {
                        if (Focus2OrMore && Me.FocusPercent >= 20) return true;
                        if (Focus25rMore && Me.FocusPercent >= 25) return true;
                        if (Focus3OrMore && Me.FocusPercent >= 30) return true;
                        if (Focus35rMore && Me.FocusPercent >= 35) return true;
                        if (Focus4OrMore && Me.FocusPercent >= 40) return true;
                        if (Focus45rMore && Me.FocusPercent >= 45) return true;
                        if (Focus5OrMore && Me.FocusPercent >= 50) return true;
                        if (Focus55rMore && Me.FocusPercent >= 55) return true;
                        if (Focus6OrMore && Me.FocusPercent >= 60) return true;
                        if (Focus65rMore && Me.FocusPercent >= 65) return true;
                        if (Focus7OrMore && Me.FocusPercent >= 70) return true;
                        if (Focus75rMore && Me.FocusPercent >= 75) return true;
                        if (Focus8OrMore && Me.FocusPercent >= 80) return true;
                        if (Focus85rMore && Me.FocusPercent >= 85) return true;
                        if (Focus9OrMore && Me.FocusPercent >= 90) return true;
                        if (Focus95rMore && Me.FocusPercent >= 95) return true;

                        if (FocusFire1OrMore && Me.GotAlivePet && Me.Pet.Auras.ContainsKey("Frenzy Effect") && Me.Pet.Auras["Frenzy Effect"].StackCount >= 1) return true;
                        if (FocusFire2OrMore && Me.GotAlivePet && Me.Pet.Auras.ContainsKey("Frenzy Effect") && Me.Pet.Auras["Frenzy Effect"].StackCount >= 2) return true;
                        if (FocusFire3OrMore && Me.GotAlivePet && Me.Pet.Auras.ContainsKey("Frenzy Effect") && Me.Pet.Auras["Frenzy Effect"].StackCount >= 3) return true;
                        if (FocusFire4OrMore && Me.GotAlivePet && Me.Pet.Auras.ContainsKey("Frenzy Effect") && Me.Pet.Auras["Frenzy Effect"].StackCount >= 4) return true;
                        if (FocusFire5OrMore && Me.GotAlivePet && Me.Pet.Auras.ContainsKey("Frenzy Effect") && Me.Pet.Auras["Frenzy Effect"].StackCount >= 5) return true;
                    }
                }

                catch{}

                return false;   // Otherwise its not going to happen
            }

        }

        /// <summary>
        /// Returns TRUE is the spell/setting is OK can it passed the various checks requested
        /// </summary>
        /// <param name="clcSettingString"></param>
        /// <param name="checkAgainstUnit"></param>
        /// <returns></returns>
        public static bool ResultOK(string clcSettingString)
        {
            return ResultOK(clcSettingString, null);
        }

        public static bool CountOfMobs(string clcSettingString, float distance)
        {
            return CountOfMobs(clcSettingString, distance, null);
        }

        public static bool CountOfMobs(string clcSettingString, float distance, WoWUnit fromUnit)
        {
            if (clcSettingString.Contains("never")) return false;
            
            if (fromUnit == null && Me.GotTarget) fromUnit = CT;

            //Logging.Log.Write("count of mobs....fromUnit name is " + fromUnit.Name);

            int countOfMobs = fromUnit.AggroUnitsNearTarget(distance).Count();

            //Logging.Log.Write("... count = " + countOfMobs);
            if (clcSettingString.Contains("always")) return true;
            if (clcSettingString.Contains("only on adds") && countOfMobs >= 2) return true;
            if (clcSettingString.Contains("3+ adds") && countOfMobs >= 3) return true;
            if (clcSettingString.Contains("4+ adds") && countOfMobs >= 4) return true;
            if (clcSettingString.Contains("5+ adds") && countOfMobs >= 5) return true;
            if (clcSettingString.Contains("6+ adds") && countOfMobs >= 6) return true;
            if (clcSettingString.Contains("7+ adds") && countOfMobs >= 7) return true;

            return false;
        }

        /// <summary>
        /// Returns TRUE is the spell/setting is OK can it passed the various checks requested
        /// </summary>
        /// <param name="clcSettingString"></param>
        /// <param name="checkAgainstUnit"></param>
        /// <returns></returns>
        public static bool ResultOK(string clcSettingString, WoWUnit checkAgainstUnit)
        {
            bool result = false;

            if (string.IsNullOrEmpty(clcSettingString)) return false;

            if (checkAgainstUnit != null)
            {
                ValidateAgainstUnit = checkAgainstUnit;
            }

            // If the pipe character exists then its a multiple option setting
            if (!clcSettingString.Contains("|"))
            {
                RawSetting = clcSettingString;
                return IsOkToRun;
            }

            // If the 'AND' string exists all logic should be considered as AND logic, otherwise, OR logic
            bool andLogic = clcSettingString.ToUpper().StartsWith("AND|");
            string workingSettingString = clcSettingString.Replace("AND|", "");
            string[] multipleSettings = workingSettingString.Split('|');

            if (andLogic) result = true;

            foreach (string setting in multipleSettings)
            {
                RawSetting = setting;
                bool answer = IsOkToRun;
                if (!andLogic && answer) { return true; }
                if (andLogic && !answer) { return false; }
            }
            return result;
        }


        /*
        private static bool IsBuffPresent(string buffToCheck)
        {
            Lua.DoString(string.Format("buffName,_,_,stackCount,_,_,_,_,_=UnitBuff(\"player\",\"{0}\")", buffToCheck));
            string buffName = Lua.GetLocalizedText("buffName", Me.BaseAddress);
            return (buffName == buffToCheck);
        }

        private static bool IsBuffPresentOnTarget(string buffToCheck)
        {
            Lua.DoString(string.Format("buffName,_,_,stackCount,_,_,_,_,_=UnitBuff(\"target\",\"{0}\")", buffToCheck));
            string buffName = Lua.GetLocalizedText("buffName", CT.BaseAddress);
            return (buffName == buffToCheck);
        }
         */
    }
}
